import 'package:flutter/material.dart';
import 'dart:math' as math;

enum JoystickMode {
  all, // 全方向控制
  horizontal, // 只有水平方向
  vertical, // 只有垂直方向
}

class JoystickControl extends StatefulWidget {
  final JoystickMode mode;
  final Function(double x, double y) onPositionChanged;

  const JoystickControl({
    super.key,
    this.mode = JoystickMode.all,
    required this.onPositionChanged,
  });

  @override
  State<JoystickControl> createState() => _JoystickControlState();
}

class _JoystickControlState extends State<JoystickControl> {
  Offset _position = Offset.zero;
  Offset _basePosition = Offset.zero;
  double _radius = 0.0;
  bool _isDragging = false;

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final size = math.min(constraints.maxWidth, constraints.maxHeight);
        _radius = size / 2;
        _basePosition = Offset(_radius, _radius);

        return Container(
          width: size,
          height: size,
          decoration: BoxDecoration(
            shape: BoxShape.circle,
            color: Theme.of(context).colorScheme.surfaceVariant,
            border: Border.all(
              color: Theme.of(context).colorScheme.primary.withOpacity(0.5),
              width: 2,
            ),
          ),
          child: GestureDetector(
            onPanStart: _onPanStart,
            onPanUpdate: _onPanUpdate,
            onPanEnd: _onPanEnd,
            child: CustomPaint(
              painter: JoystickPainter(
                position: _position,
                basePosition: _basePosition,
                radius: _radius,
                isDragging: _isDragging,
                theme: Theme.of(context),
              ),
            ),
          ),
        );
      },
    );
  }

  void _onPanStart(DragStartDetails details) {
    final RenderBox box = context.findRenderObject() as RenderBox;
    final localPosition = box.globalToLocal(details.globalPosition);
    _updateJoystickPosition(localPosition);
  }

  void _onPanUpdate(DragUpdateDetails details) {
    final RenderBox box = context.findRenderObject() as RenderBox;
    final localPosition = box.globalToLocal(details.globalPosition);
    _updateJoystickPosition(localPosition);
  }

  void _onPanEnd(DragEndDetails details) {
    setState(() {
      _position = Offset.zero;
      _isDragging = false;
    });
    widget.onPositionChanged(0, 0);
  }

  void _updateJoystickPosition(Offset localPosition) {
    // 计算相对于中心的位置
    Offset relativePosition = localPosition - _basePosition;
    
    // 根据模式限制方向
    switch (widget.mode) {
      case JoystickMode.horizontal:
        relativePosition = Offset(relativePosition.dx, 0);
        break;
      case JoystickMode.vertical:
        relativePosition = Offset(0, relativePosition.dy);
        break;
      case JoystickMode.all:
        // 不做限制
        break;
    }
    
    // 限制在圆内
    double distance = relativePosition.distance;
    if (distance > _radius * 0.8) {
      relativePosition = relativePosition * (_radius * 0.8 / distance);
    }
    
    setState(() {
      _position = relativePosition;
      _isDragging = true;
    });
    
    // 计算标准化的位置 (-1 到 1 之间)
    double normalizedX = relativePosition.dx / (_radius * 0.8);
    double normalizedY = relativePosition.dy / (_radius * 0.8);
    
    // 回调通知位置变化
    widget.onPositionChanged(normalizedX, normalizedY);
  }
}

class JoystickPainter extends CustomPainter {
  final Offset position;
  final Offset basePosition;
  final double radius;
  final bool isDragging;
  final ThemeData theme;

  JoystickPainter({
    required this.position,
    required this.basePosition,
    required this.radius,
    required this.isDragging,
    required this.theme,
  });

  @override
  void paint(Canvas canvas, Size size) {
    // 绘制中心点
    final centerPaint = Paint()
      ..color = theme.colorScheme.primary.withOpacity(0.3)
      ..style = PaintingStyle.fill;
    canvas.drawCircle(basePosition, radius * 0.2, centerPaint);

    // 绘制十字线
    final linePaint = Paint()
      ..color = theme.colorScheme.onSurfaceVariant.withOpacity(0.3)
      ..strokeWidth = 1.0
      ..style = PaintingStyle.stroke;

    // 水平线
    canvas.drawLine(
      Offset(basePosition.dx - radius * 0.8, basePosition.dy),
      Offset(basePosition.dx + radius * 0.8, basePosition.dy),
      linePaint,
    );

    // 垂直线
    canvas.drawLine(
      Offset(basePosition.dx, basePosition.dy - radius * 0.8),
      Offset(basePosition.dx, basePosition.dy + radius * 0.8),
      linePaint,
    );

    // 绘制操纵杆
    final joystickPaint = Paint()
      ..color = isDragging
          ? theme.colorScheme.primary
          : theme.colorScheme.primary.withOpacity(0.7)
      ..style = PaintingStyle.fill;

    canvas.drawCircle(
      basePosition + position,
      radius * 0.25,
      joystickPaint,
    );

    // 绘制操纵杆边框
    final joystickBorderPaint = Paint()
      ..color = theme.colorScheme.onPrimary
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.0;

    canvas.drawCircle(
      basePosition + position,
      radius * 0.25,
      joystickBorderPaint,
    );
  }

  @override
  bool shouldRepaint(JoystickPainter oldDelegate) {
    return position != oldDelegate.position || isDragging != oldDelegate.isDragging;
  }
} 